Skip to content

feat(api): document measured-power contract and add powerValid filter | API:文档化实测功率契约并新增 powerValid 筛选参数 - #938

Merged
edwingao28 merged 13 commits into
masterfrom
feat/api-power-contract
Sep 4, 2026
Merged

feat(api): document measured-power contract and add powerValid filter | API:文档化实测功率契约并新增 powerValid 筛选参数#938
edwingao28 merged 13 commits into
masterfrom
feat/api-power-contract

Conversation

@edwingao28

@edwingao28 edwingao28 commented Aug 28, 2026

Copy link
Copy Markdown
Collaborator

Summary | 概要

Adds a typed, documented measured-power contract to the public benchmarks API. The only explicit power filter is powerValid=strictV2; the transitional 1, 0, and any modes have been removed before rollout.

为公开基准测试 API 提供带类型、有文档的实测功率契约。唯一接受的显式功率筛选值为 powerValid=strictV2;上线前移除过渡性的 10any 选项。

Final API contract | 最终 API 契约

  • GET /api/v1/benchmarks?model=DeepSeek-R1-0528&powerValid=strictV2 keeps only rows with numeric metrics.power_valid === 1 and numeric metrics.power_metric_schema_version === 2.
    仅保留 metrics.power_valid 为数字 1、且 metrics.power_metric_schema_version 为数字 2 的数据行。
  • Omit powerValid for ordinary benchmark requests. Throughput and latency results remain available even when power is missing or invalid.
    常规基准测试请求省略 powerValid。即使功率缺失或无效,也会保留吞吐量和延迟结果。
  • Any other supplied value, including 1, 0, any, certified, and the empty string, returns HTTP 400 Unknown powerValid filter.
    其他显式取值(包括上述旧选项及空字符串)均返回 HTTP 400 Unknown powerValid filter
  • powerValid=strictV2 cannot be combined with view=calculator, because calculator projections omit the power verdict. Calculator requests still work when powerValid is omitted.
    计算器投影不包含功率验证字段,因此不能与 powerValid=strictV2 组合使用;省略 powerValid 的计算器请求不受影响。

Implementation | 实现

Scope | 范围

This retires public filter options, not the producer's internal valid/invalid verdict fields. Dashboard measured-power defaults and the UI's broader Certified tier are unchanged. This API change does not itself certify new measurements or supply missing producer telemetry/provenance.

本次移除的是公开筛选选项,不是生产端内部的有效/无效判定字段。仪表盘实测功率默认值及界面中范围更宽的 Certified 档位保持不变。本次 API 变更本身不会认证新的测量结果,也不会补齐生产端缺失的遥测或溯源数据。

Validation | 验证

  • Full workspace unit suite: 5,712 passed (app 4,949; constants 53; db 685; mcp 25).
    全工作区单元测试:5,712 项通过
  • Cypress fixture-mode quick smoke: 46 component + 113 integration checks passed.
    Cypress 夹具模式快速冒烟检查:46 项组件检查及 113 项集成检查通过
  • Targeted api-documentation.cy.ts: 4 passed, covering English/Chinese pages, OpenAPI, strict filtering, rejected values, omission, and calculator compatibility.
    定向 API 文档测试:4 项通过,覆盖中英文页面、OpenAPI、严格筛选、无效取值、省略参数及计算器兼容行为。
  • Typecheck, lint, formatting, typography, and diff checks passed.
    类型检查、静态检查、格式、排版及差异检查均通过。

Rollback | 回滚

Revert this PR. No migrations, cache-key changes, or data writes.

回退本 PR 即可;不涉及数据库迁移、缓存键变更或数据写入。


Note

Medium Risk
Changes a stable public benchmarks endpoint and published OpenAPI contract; behavior is backward compatible when powerValid is omitted, but clients using new filters or relying on undocumented calculator params need correct combinations.

Overview
Adds a documented measured-power surface and an optional powerValid filter on GET /api/v1/benchmarks. Omitting the parameter leaves responses unchanged; powerValid=strictV2 keeps only rows with metrics.power_valid === 1 and metrics.power_metric_schema_version === 2. Any other value (including empty) returns 400 Unknown powerValid filter; powerValid cannot be combined with view=calculator because calculator rows are trimmed before power fields exist.

OpenAPI and the /api pages gain typed 15 power-related metrics keys via POWER_METRIC_KEYS, optional row fields power_invalid_reasons and power_audit, formally documented view/sequence, and a bilingual Measured power schema note. Filtering runs post-cache through benchmark-power-validity.ts; the route catalog digest and contract parameter list are updated. Unit, documentation, and Cypress tests cover filter behavior and the published contract.

Reviewed by Cursor Bugbot for commit 9814321. Bugbot is set up for automated code reviews on this repo. Configure here.

…t | 常量:提取 MEASURED_POWER_METRIC_KEYS 作为需扣留的实测功耗指标集合

Move the 13 measured power / energy / GPU-telemetry keys out of the
METRIC_KEYS literal into an exported MEASURED_POWER_METRIC_KEY_LIST (and
ReadonlySet MEASURED_POWER_METRIC_KEYS) so the ingest scrub and the
display-layer withholding share one source of truth. METRIC_KEYS
membership is unchanged (spread keeps the same entries); the contract
discriminators power_valid / power_metric_schema_version and the
invalid-verdict companion fields power_invalid_reasons / power_audit are
codified as never part of the withheld set.

将 13 个实测功耗/能耗/GPU 遥测指标键从 METRIC_KEYS 字面量中提取为导出的
MEASURED_POWER_METRIC_KEY_LIST(及 ReadonlySet 形式的
MEASURED_POWER_METRIC_KEYS),使摄取端剥离逻辑与前端展示层扣留逻辑共享
单一事实来源。METRIC_KEYS 成员保持不变;契约判别字段与无效判定伴随字段
经测试固定永不进入扣留集合。
… ETL:power_valid=0 时在摄取阶段剥离实测功耗指标

Defense-in-depth for the power publication contract (G8). Today the only
protections are producer-side stripping (aggregate_power.py) and the
frontend display withholding — the ETL persists, and the raw API serves,
whatever measured values a power_valid=0 artifact carries. Add
scrubWithheldPowerMetrics to mapBenchmarkRow: after the normalized
verdict fails closed to 0, delete every MEASURED_POWER_METRIC_KEYS entry
and drop the workers payload. The scrub runs after the last metrics
mutation (agentic preferFullResponseMetrics reassignment +
extractRuntimeMetadata merge), covers every ingest path (CI ingest and
both re-mapping backfills), is idempotent, and converges re-ingested
dirty artifacts to exactly what a clean producer would ship. Verdict
discriminators, companion fields (power_invalid_reasons / power_audit),
legacy no-verdict rows, and pv=1 rows are untouched. The query layer
deliberately stays unfiltered (single enforcement point at ETL).

针对功耗发布契约的纵深防御(G8)。此前仅有生产端剥离与前端展示扣留两道
防线:power_valid=0 的工件若携带实测值,ETL 会照常入库、原始 API 会照常
返回。本次在 mapBenchmarkRow 中新增 scrubWithheldPowerMetrics:判定值
归一化为 0 后,删除 MEASURED_POWER_METRIC_KEYS 中的全部指标并丢弃
workers 载荷。剥离在最后一次 metrics 变更之后执行,覆盖所有摄取路径,
幂等且使脏工件重摄取后与清洁生产端输出完全一致。判别字段、伴随字段、
无判定的历史行及 power_valid=1 的行均不受影响;查询层有意保持不过滤
(ETL 为唯一强制点)。
…KEYS | 测试:前端展示层扣留逻辑与 MEASURED_POWER_METRIC_KEYS 保持一致

Drive rowToAggDataEntry with a power_valid=0 row carrying every key in
the shared constant and assert each corresponding output field (and
workers) comes back undefined — adding a key to the constant that the
frontend forgets to withhold now fails this test. The reverse direction
(frontend withholding a key missing from the constant) stays
hand-audited, as noted in the test comment.

以携带共享常量中全部键的 power_valid=0 行驱动 rowToAggDataEntry,断言
对应输出字段(含 workers)均为 undefined —— 若向常量新增了前端未扣留的
键,此测试即失败。反向情况(前端扣留了常量之外的键)仍由人工审计,测试
注释中已注明。
…apBenchmarkRow 的补充数据摄取同样应用功耗剥离

Review found ingest-supplemental.ts persists metrics verbatim via
bulkIngestBenchmarkRows without mapBenchmarkRow, so a supplemental
entry carrying power_valid=0 plus measured values would have bypassed
the scrub. Export normalizePowerContractMetrics /
scrubWithheldPowerMetrics and run the same fail-closed normalize+scrub
pair on supplemental metrics; correct the scrub docstring to name the
path; pin the direct-call usage with unit tests.
…量:导出 POWER_METRIC_KEYS 功率契约指标键列表

Derives the full documented power surface (discriminators +
MEASURED_POWER_METRIC_KEY_LIST) as one exported constant and spreads it
into METRIC_KEYS, keeping set membership provably unchanged. The public
API documentation layer types BenchmarkRow.metrics from this export.
…enchmarks | API:为 /api/v1/benchmarks 新增 powerValid 实测功率有效性筛选参数

Pure post-cache row filter (cache keys unchanged): 1 keeps validated
rows, 0 keeps explicitly invalidated rows, any is the default identity
(legacy rows included), and strictV2 additionally requires
power_metric_schema_version == 2 (whole-deployment energy semantics).
Named strictV2 rather than certified to avoid colliding with the UI
tier's product meaning. Unknown values 400; the combination with
view=calculator 400s because the calculator cache stores rows already
trimmed past power_valid. Route digest bumped in the review ledger.
… | 文档:为 /api/v1/benchmarks 文档化实测功率契约

Types every POWER_METRIC_KEYS entry on the BenchmarkRow metrics schema
(additionalProperties still admits non-power keys), reserves the
forthcoming power_invalid_reasons / power_audit row fields from the
cross-plan producer contract, documents the previously-undocumented
view/sequence params plus the new powerValid param, adds a bilingual
measured-power schema note (tri-state power_valid, schema-version-2
whole-deployment energy, workers[] relationship, strictV2-vs-UI
divergence), and mirrors the parameter list in the stable contract
ledger. Cypress asserts the note and param render on /api and /zh/api.
…00 | 文档:说明 powerValid=any 可与 view=calculator 组合的例外

Review finding: the route only rejects non-any powerValid with
view=calculator, but the published copy claimed the combination is
always invalid. Align the operation description, the powerValid param
description, and the 400 response description (EN + ZH) with actual
behavior.
@edwingao28
edwingao28 requested a review from adibarra as a code owner August 28, 2026 02:55
@vercel

vercel Bot commented Aug 28, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
inferencemax-app Ready Ready Preview Sep 4, 2026 10:29pm UTC

Request Review

@github-actions

github-actions Bot commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Claude finished @edwingao28's task in 2m 46s —— View job


Review complete — 🟢 LGTM

  • Read the diff against feat/etl-invalid-power-scrub
  • Review benchmark-power-validity.ts filter logic
  • Review route.ts integration + 400 handling
  • Review api-documentation.ts + constants changes
  • Check test coverage
  • Runtime verification on the dev server
  • Chinese copy review (review-zh-copy)

No blocking or warning issues found. This is a clean, backward-compatible, well-tested change.

What I verified at runtime (dev server, real read-only DB)

Check Result
powerValid=garbage 400 {"error":"Unknown powerValid filter"}
powerValid=1&view=calculator 400 {"error":"powerValid cannot be combined with view=calculator"}
powerValid=any&view=calculator 200 (no-op) ✅
absent vs powerValid=any byte-identical response ✅ (backward compat)
powerValid=1/0/strictV2 on current data 0 rows — every live row has power_valid: null (contract is forthcoming), and legacy rows correctly match only any
openapi.json powerValid enum ["1","0","any","strictV2"], metrics.power_valid typed, power_invalid_reasons reserved ✅

The unknown-value 400 short-circuits before the DB query, and the calculator-combination rejection is correctly ordered after it (an unknown value beats the combination error). Filter is a pure post-cache pass with no cache-key changes, so no blob-cache fragmentation.

Correctness notes

  • filterByPowerValidity matches the documented tri-state contract: === 1 / === 0 numeric checks align with the power_valid: numeric 1/0 producer contract, and strictV2 correctly requires power_metric_schema_version === 2. Rows without metrics or without a verdict fall through to any-only, as documented.
  • POWER_METRIC_KEYS refactor is a pure extraction — spread back into METRIC_KEYS, so set membership is provably unchanged and test-asserted (metric-keys.test.ts).
  • metricMapSchema is still used elsewhere (line 392), so the switch to benchmarkMetricsSchema on BenchmarkRow.metrics leaves no dead code.

Test coverage

Strong. New colocated benchmark-power-validity.test.ts (parser + filter, incl. certified non-aliasing and case-sensitivity), api-documentation.power.test.ts, 8 new route cases (filters, 400s, any≡absent compat, calculator no-op, agentic-metadata composition), and metric-keys.test.ts assertions pinning the 15-key contract.

Chinese copy

All six changed zh passages reviewed against their English sources — accurate and natural for the API-reference surface. No fidelity or naturalness findings; no maintainer escalation needed.

Note

Stacked PR — as the description states, this must land after #937 (feat/etl-invalid-power-scrub) and be retargeted to master. The dedicated tests-*/lint workflows did not appear in gh pr checks at review time (only Vercel + Claude + Bugbot); worth confirming they run green before merge, though the author reports all suites passing locally.

中文:清理功耗剥离相关测试与实现注释,移除内部计划编号,并保留关键的故障关闭与摄取顺序语义。
中文:清理内部规划标签和冗余叙述,并以当前契约语义明确功率审计字段说明。
中文:合并更新后的功耗剥离基础分支并保留公开 API 契约
@github-actions

github-actions Bot commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Claude finished @edwingao28's task in 2m 10s —— View job


Re-review — 🟢 LGTM

  • Read new commits since last LGTM review
  • Review filter logic + route integration
  • Review docs/constants/ledger changes
  • Check CI status
  • Runtime verification of powerValid filter + docs
  • Post review

What changed since the last review (f8fb515e07b9d25d): only the base-branch merge "chore: merge updated power scrub base", which brings comment simplifications in benchmark-mapper.ts / metric-keys.ts and removes some now-redundant test comments. Those files belong to the stacked base #937 and don't appear in this PR's own diff (origin/feat/etl-invalid-power-scrub...HEAD). No functional change to this PR since the previous approval. The powerValid filter, docs contract, and constants extraction are unchanged and remain correct.

Runtime verification (dev server, real read-only DB)

Check Result
powerValid=garbage 400 {"error":"Unknown powerValid filter"}
view=calculator&powerValid=1 400 {"error":"powerValid cannot be combined with view=calculator"}
view=calculator&powerValid=any 200 (no-op) ✅
absent vs powerValid=any byte-identical response ✅
openapi.json powerValid param enum + full description present ✅
/api + /zh/api "Measured power" / "实测功率" note both render ✅

The unknown-value 400 short-circuits before the calculator-combination 400 (verified), and the filter is a pure post-cache pass with no cache-key changes.

Notes

No blocking or warning issues found.
· feat/api-power-contract

Base automatically changed from feat/etl-invalid-power-scrub to master September 4, 2026 21:27
中文:解决 API 功率契约与 master 的合并冲突。
@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Claude finished @edwingao28's task in 1m 31s —— View job


Re-review — 🟢 LGTM

  • Identify new commits since last review
  • Review filter logic + route integration
  • Review docs/constants/ledger changes
  • Check CI status
  • Runtime verification of powerValid filter

What changed since the last LGTM (07b9d25d4c838e88): a single merge commit — "chore: resolve API power contract conflicts" — that brings master into the branch now that #937 has landed, retargeting the PR to master. It only touches unrelated master files (workflows, docs, blog MDX, bun.lock, cypress config, etc.); this PR's own 10 files (benchmark-power-validity.ts, route.ts, api-documentation.ts, constants, ledger, tests) are unchanged from the previously-approved state. No functional change to this PR since the previous approval.

CI status

Check Result
Tests (Unit) ✅ success (includes api-route-catalog digest/parity + metric-keys contract assertions)
Lint & Format ✅ success
Tests (E2E) ⏳ in progress at review time

The merge-gate caveat from the prior reviews is now resolved — the dedicated tests-unit / tests-e2e / lint workflows do run against master as the base.

Runtime verification (dev server, real read-only DB)

Check Result
powerValid=garbage 400 {"error":"Unknown powerValid filter"}
powerValid=1&view=calculator 400 {"error":"powerValid cannot be combined with view=calculator"}
powerValid=any&view=calculator 200 (no-op) ✅
absent vs powerValid=any byte-identical ✅ (backward compat)
powerValid=1 / 0 / strictV2 200, 0 rows (no live row has power_valid yet — contract forthcoming, matches prior review) ✅

Error ordering is correct: unknown-value 400 short-circuits before the calculator-combination 400; the filter is a pure post-cache pass with no cache-key changes.

No blocking or warning issues found. Wait for the E2E workflow to go green before merge.
· feat/api-power-contract

仅接受 strictV2 作为公开功率筛选值;省略参数时保留常规基准结果。同步更新中英文文档、OpenAPI 契约和回归测试。
@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

Claude finished @edwingao28's task in 2m 0s —— View job


Re-review — 🟢 LGTM

  • Identify new commits since last review (4c838e88)
  • Review the new strictV2 restriction change
  • Check CI status
  • Runtime verification
  • Post review

What changed since the last LGTM (4c838e8898143219): a single functional commit — "fix(api): restrict power filtering to strictV2". The powerValid param, previously {1, 0, any, strictV2} (default any), now accepts only strictV2 (or absence). This is a deliberate narrowing, and it's applied consistently across every surface:

  • benchmark-power-validity.tsparsePowerValidityFilter now returns null (absent → no filter), 'strictV2', or undefined (anything else → caller 400s). filterByPowerValidity takes PowerValidityFilter | null; null returns a copy, strictV2 requires power_valid === 1 && power_metric_schema_version === 2. Clean.
  • route.ts — the calculator-combination guard correctly switched from !== 'any' to !== null, so it now rejects strictV2 but permits an omitted param. Error ordering preserved (unknown-value 400 short-circuits before the calculator 400 and before the DB query).
  • api-documentation.ts — operation/param/400/measured-power copy (EN + ZH) all rewritten to describe strictV2-only; OpenAPI schema drops default: 'any' and narrows the enum to ['strictV2'].
  • api-route-catalog.ts — route digest recomputed.

CI status

Check Result
Tests (Unit) ✅ success (api-route-catalog digest/parity + metric-keys contract)
Lint & Format ✅ success
Tests (E2E) ⏳ in progress at review time

Runtime verification (dev server, real read-only DB)

Check Result
absent 200, 1310 rows (unfiltered) ✅
powerValid=strictV2 200, 0 rows (no live row has valid v2 power yet — contract forthcoming, matches prior reviews) ✅
powerValid=any / 1 / garbage 400 {"error":"Unknown powerValid filter"}
view=calculator&powerValid=strictV2 400 {"error":"powerValid cannot be combined with view=calculator"}
view=calculator (absent) 200
openapi.json powerValid required:false, schema:{type:'string',enum:['strictV2']}, no default

Test coverage

Adequate and updated in lockstep: benchmark-power-validity.test.ts (null-absent, strictV2 accept, it.each rejection incl. strictV2 trailing-space + wrong-typed verdicts), route.test.ts (strictV2 filter, omitted-param passthrough, it.each 400 for 1/0/any/certified/garbage/''/strictv2, calculator combos, agentic-metadata composition), api-documentation.power.test.ts and the Cypress spec (enum/required + live strictV2 vs raw parity). No missing-test gap.

Chinese copy

The new commit rewrote the ZH powerValid param, 400, operation, and measured-power note passages alongside their English sources. All four are accurate and natural for the API-reference surface (e.g. metrics.power_valid 为数字 1 correctly pins the numeric type; 不按功率筛选 reads idiomatically). No fidelity or naturalness findings; no maintainer escalation needed.

Note: this narrows an accepted-value set relative to the earlier state of this same (unmerged) PR, so there's no external contract break — but it does mean any/1/0 now 400 rather than filter. Intentional per the commit. Wait for E2E to go green before merge.
· feat/api-power-contract

@edwingao28
edwingao28 merged commit cc5d87c into master Sep 4, 2026
25 checks passed
@edwingao28
edwingao28 deleted the feat/api-power-contract branch September 4, 2026 23:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant